﻿using System.Collections.Generic;
using PetaPoco;

namespace Common.Orm
{
    public class Condition
    {
        private string _name;
        private string _operation;
        private object _value;
        private Condition()
        {
            conditions = new List<Condition>();
        }
        public Condition(string name, string operation, object value)
            : this()
        {
            _name = name;
            _operation = operation;
            _value = value;
        }

        private readonly List<Condition> conditions;


        private List<Condition> GetCondications { get { return conditions; } }

        public static Condition Builder
        {
            get { return new Condition(); }
        }

        public Condition Equal(string name, object value)
        {
            return Common(name, "=", value);
        }
        public Condition NotEqual(string name, object value)
        {
            return Common(name, "<>", value);
        }
        public Condition Like(string name, object value)
        {
            if (value != null && value.ToString() != "")
            {
                return Common(name, "like", "%" + value + "%");
            }
            return this;
        }
        public Condition LeftLike(string name, object value)
        {
            if (value != null && value.ToString() != "")
            {
                return Common(name, "like", "%" + value);
            }
            return this;
        }
        public Condition RightLike(string name, object value)
        {
            if (value != null && value.ToString() != "")
            {
                return Common(name, "like", value + "%");
            }
            return this;
        }
        public Condition In(string name, object value)
        {
            return Common(name, "in", value);
        }

        public Condition Gt(string name, object value)
        {
            return Common(name, ">", value);
        }
        public Condition GtEqual(string name, object value)
        {
            return Common(name, ">=", value);
        }

        public Condition Lt(string name, object value)
        {
            return Common(name, "<", value);
        }
        public Condition LtEqual(string name, object value)
        {
            return Common(name, "<=", value);
        }

        private Condition Common(string name, string operation, object value)
        {
            if (value != null)
                if (!string.IsNullOrEmpty(value.ToString()))
                    conditions.Add(new Condition(name, operation, value));
            return this;
        }

        public Sql Create()
        {
            Sql sql = Sql.Builder;
            for (int i = 0; i < GetCondications.Count; i++)
            {
                if (i == 0)
                {
                    sql.Where(GetWhereSql(GetCondications[i]._name, GetCondications[i]._operation), GetCondications[i]._value);
                }
                else
                {
                    sql.Append("AND (" + GetWhereSql(GetCondications[i]._name, GetCondications[i]._operation) + ")", GetCondications[i]._value);
                }
            }
            return sql;
        }

        private string GetWhereSql(string name, string operation)
        {
            switch (operation)
            {
                case "=":
                    return name + operation + "@0";
                case "<>":
                    return name + operation + "@0";
                case ">":
                    return name + operation + "@0";
                case ">=":
                    return name + operation + "@0";
                case "<":
                    return name + operation + "@0";
                case "<=":
                    return name + operation + "@0";
                case "like":
                    return name + " like @0";
                case "in":
                    return name + " in (@0)";
            }
            return string.Empty;
        }
    }

}